misc improvements. (#861)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Wed, 9 Mar 2022 16:34:26 +0000 (09:34 -0700)
committerGitHub <noreply@github.com>
Wed, 9 Mar 2022 16:34:26 +0000 (09:34 -0700)
* misc improvements.

fix memory leak in nmea reader.
eliminate extra string conversion using xml_parse_time.
use local QByteArray instead of xstrdup.
convert human_to_dec interface to QString.

* use strtod to track converted len in human_to_dec.

* enhance humantodec test.

csv_util.cc
csv_util.h
gpx.cc
nmea.cc
reference/humantodec.gpx [new file with mode: 0644]
reference/humantodec1.csv [new file with mode: 0644]
reference/humantodec2.csv [new file with mode: 0644]
testo.d/unicsv.test
xcsv.cc

index f522bee69316056532f3b20d8acd2c3c12307417..65448e24fb1cb4a623a7babb155531a1e16fb8ec 100644 (file)
  */
 
 #include <cassert>             // for assert
-#include <cctype>              // for isspace
 #include <cmath>               // for fabs
-#include <cstdio>              // for size_t
 #include <cstdlib>             // for atof, strtod
 #include <cstring>             // for strlen, strchr, strncmp, strcmp, memmove, strcpy, strcspn, strncpy
 
+#include <QByteArray>          // for QByteArray
 #include <QChar>               // for QChar
 #include <QDebug>              // for QDebug
 #include <QRegularExpression>  // for QRegularExpression
@@ -331,14 +330,14 @@ ddmmdir_to_degrees(const char* ddmmdir)
 
 /*****************************************************************************
  * human_to_dec() - convert a "human-readable" lat and/or lon to decimal
- * usage: human_to_dec( "N 41� 09.12' W 085� 09.36'", &lat, &lon );
+ * usage: human_to_dec( "N 41° 09.12′ W 085° 09.36′", &lat, &lon );
  *        human_to_dec( "41 9 5.652 N", &lat, &lon );
  *
  *        which: 0-no preference    1-prefer lat    2-prefer lon
  *****************************************************************************/
 
 void
-human_to_dec(const char* instr, double* outlat, double* outlon, int which)
+human_to_dec(const QString& instr, double* outlat, double* outlon, int which)
 {
   double unk[3] = {999,999,999};
   double lat[3] = {999,999,999};
@@ -347,21 +346,12 @@ human_to_dec(const char* instr, double* outlat, double* outlon, int which)
   int    lonsign = 0;
   int    unksign = 1;
 
-  const char* cur;
   double* numres = unk;
   int numind = 0;
-  char* buff = nullptr;
 
-  if (strchr(instr, ',') != nullptr) {
-    char* c;
-    buff = xstrdup(instr);
-    while ((c = strchr(buff, ','))) {
-      *c = '.';
-    }
-    cur = buff;
-  } else {
-    cur = instr;
-  }
+  // Allow comma as decimal separator.
+  const QByteArray inbytes = instr.toUtf8().replace(',', '.');
+  const char* cur = inbytes.constData();
 
   while (cur && *cur) {
     switch (*cur) {
@@ -424,11 +414,9 @@ human_to_dec(const char* instr, double* outlat, double* outlon, int which)
     case '9':
     case '0':
     case '.':
-    case ',':
-      numres[numind] = atof(cur);
-      while (cur && *cur && strchr("1234567890.,",*cur)) {
-        cur++;
-      }
+      char* end;
+      numres[numind] = strtod(cur, &end);
+      cur = end;
       break;
     case '-':
       unksign = -1;
@@ -495,9 +483,6 @@ human_to_dec(const char* instr, double* outlat, double* outlon, int which)
       *outlon *= lonsign;
     }
   }
-  if (buff) {
-    xfree(buff);
-  }
 }
 
 /*
index c0461bb24546ca146b168b612bbfb1c115b6bca3..57789407e7d747ec804b8b7910396e3f2f0eaa41 100644 (file)
@@ -58,11 +58,7 @@ double
 ddmmdir_to_degrees(const char* ddmmdir);
 
 void
-human_to_dec(const char* instr, double* outlat, double* outlon, int which);
-inline void
-human_to_dec(const QString& instr, double* outlat, double* outlon, int which) {
-  human_to_dec(CSTR(instr), outlat, outlon, which);
-}
+human_to_dec(const QString& instr, double* outlat, double* outlon, int which);
 
 QString
 dec_to_human(const char* format, const char* dirs, double val);
diff --git a/gpx.cc b/gpx.cc
index 5db2f75defa7db3f961bb04128b7fbb6aade532a..b6803bf78a7e5ebfc82d12df1f2670b43de0a64b 100644 (file)
--- a/gpx.cc
+++ b/gpx.cc
@@ -487,7 +487,9 @@ xml_parse_time(const QString& dateTimeString)
   int off_hr = 0;
   int off_min = 0;
   int off_sign = 1;
-  char* timestr = xstrdup(dateTimeString);
+
+  QByteArray dts = dateTimeString.toUtf8();
+  char* timestr = dts.data();
 
   char* offsetstr = strchr(timestr, 'Z');
   if (offsetstr) {
@@ -545,7 +547,6 @@ xml_parse_time(const QString& dateTimeString)
   } else {
     dt = QDateTime();
   }
-  xfree(timestr);
   return dt;
 }
 
diff --git a/nmea.cc b/nmea.cc
index 92d284c08ddad16d6abb2e992d43ab1587dbcba5..dac71f88b0e5b1852c651287e003fb8c85da9d2d 100644 (file)
--- a/nmea.cc
+++ b/nmea.cc
@@ -271,6 +271,9 @@ NmeaFormat::rd_deinit()
     break;
   }
 
+  nmea_release_wpt(curr_waypt);
+  curr_waypt = nullptr;
+
   posn_fname.clear();
 
 }
diff --git a/reference/humantodec.gpx b/reference/humantodec.gpx
new file mode 100644 (file)
index 0000000..37bfa1d
--- /dev/null
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gpx version="1.0" creator="GPSBabel - https://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0">
+  <time>1970-01-01T00:00:00Z</time>
+  <bounds minlat="-1.234000000" minlon="-5.678000000" maxlat="-1.234000000" maxlon="-5.678000000"/>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point0</name>
+    <cmt>point0</cmt>
+    <desc>point0</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point1</name>
+    <cmt>point1</cmt>
+    <desc>point1</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point2</name>
+    <cmt>point2</cmt>
+    <desc>point2</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point3</name>
+    <cmt>point3</cmt>
+    <desc>point3</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point4</name>
+    <cmt>point4</cmt>
+    <desc>point4</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point5</name>
+    <cmt>point5</cmt>
+    <desc>point5</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point6</name>
+    <cmt>point6</cmt>
+    <desc>point6</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point7</name>
+    <cmt>point7</cmt>
+    <desc>point7</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point8</name>
+    <cmt>point8</cmt>
+    <desc>point8</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point9</name>
+    <cmt>point9</cmt>
+    <desc>point9</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point10</name>
+    <cmt>point10</cmt>
+    <desc>point10</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point11</name>
+    <cmt>point11</cmt>
+    <desc>point11</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point12</name>
+    <cmt>point12</cmt>
+    <desc>point12</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point13</name>
+    <cmt>point13</cmt>
+    <desc>point13</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point14</name>
+    <cmt>point14</cmt>
+    <desc>point14</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point15</name>
+    <cmt>point15</cmt>
+    <desc>point15</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point16</name>
+    <cmt>point16</cmt>
+    <desc>point16</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point17</name>
+    <cmt>point17</cmt>
+    <desc>point17</desc>
+  </wpt>
+  <wpt lat="-1.234000000" lon="-5.678000000">
+    <name>point18</name>
+    <cmt>point18</cmt>
+    <desc>point18</desc>
+  </wpt>
+</gpx>
diff --git a/reference/humantodec1.csv b/reference/humantodec1.csv
new file mode 100644 (file)
index 0000000..5b12efd
--- /dev/null
@@ -0,0 +1,20 @@
+lat,lon,desc
+1.234°S,5.678°W,point0
+1°14.04′S,5°40.68′W,point1
+1°14′2.4″S,5°40′40.8″W,point2
+S1.234°,W5.678°,point3
+S1°14.04′,W5°40.68′,point4
+S1°14′2.4″,W5°40′40.8″,point5
+-1.234°,-5.678°,point6
+-1°14.04′,-5°40.68′,point7
+-1°14′2.4″,-5°40′40.8″,point8
+1.234° S,5.678° W,point9
+1° 14.04′ S,5° 40.68′ W,point10
+1° 14′ 2.4″ S,5° 40′ 40.8″ W,point11
+S 1.234°,W 5.678°,point12
+S 1° 14.04′,W 5° 40.68′,point13
+S 1° 14′ 2.4″,W 5° 40′ 40.8″,point14
+-1.234°,-5.678°,point15
+-1° 14.04′,-5° 40.68′,point16
+-1° 14′ 2.4″,-5° 40′ 40.8″,point17
+-1.234,-5.678,point18
diff --git a/reference/humantodec2.csv b/reference/humantodec2.csv
new file mode 100644 (file)
index 0000000..497c532
--- /dev/null
@@ -0,0 +1,20 @@
+lat    lon     desc
+1,234°S       5,678°W        point0
+1°14,04′S   5°40,68′W    point1
+1°14′2,4″S        5°40′40,8″W        point2
+S1,234°       W5,678°        point3
+S1°14,04′   W5°40,68′    point4
+S1°14′2,4″        W5°40′40,8″        point5
+-1,234°       -5,678°        point6
+-1°14,04′   -5°40,68′    point7
+-1°14′2,4″        -5°40′40,8″        point8
+1,234° S      5,678° W       point9
+1° 14,04′ S 5° 40,68′ W  point10
+1° 14′ 2,4″ S     5° 40′ 40,8″ W     point11
+S 1,234°      W 5,678°       point12
+S 1° 14,04′ W 5° 40,68′  point13
+S 1° 14′ 2,4″     W 5° 40′ 40,8″     point14
+-1,234°       -5,678°        point15
+-1° 14,04′  -5° 40,68′   point16
+-1° 14′ 2,4″      -5° 40′ 40,8″      point17
+-1,234 -5,678  point18
index 03383562a83327dc94dbe05892b57989773c5c2a..115a92bea789e1dfe83a641317af8049f8e0676e 100644 (file)
@@ -41,3 +41,8 @@ compare ${REFERENCE}/libreoffice.text ${TMPDIR}/libreoffice.text
 gpsbabel -i unicsv -f ${REFERENCE}/libreoffice.csv -o unicsv -F ${TMPDIR}/libreoffice2.csv
 gpsbabel -i unicsv -f ${TMPDIR}/libreoffice2.csv -o text,degformat=ddd -F ${TMPDIR}/libreoffice2.text
 compare ${REFERENCE}/libreoffice.text ${TMPDIR}/libreoffice2.text
+
+gpsbabel -i unicsv -f ${REFERENCE}/humantodec1.csv -o gpx -F ${TMPDIR}/humantodec1.gpx
+compare ${REFERENCE}/humantodec.gpx ${TMPDIR}/humantodec1.gpx
+gpsbabel -i unicsv -f ${REFERENCE}/humantodec2.csv -o gpx -F ${TMPDIR}/humantodec2.gpx
+compare ${REFERENCE}/humantodec.gpx ${TMPDIR}/humantodec2.gpx
diff --git a/xcsv.cc b/xcsv.cc
index f161c7952ec5bf165e6aef5e7662c61d67264661..99a9543c05122bdf34fd42e3ba2942ebaed6cf0e 100644 (file)
--- a/xcsv.cc
+++ b/xcsv.cc
@@ -455,7 +455,7 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
     wpt->latitude = intdeg_to_dec((int) atof(s));
     break;
   case XcsvStyle::XT_LAT_HUMAN_READABLE:
-    human_to_dec(s, &wpt->latitude, &wpt->longitude, 1);
+    human_to_dec(value, &wpt->latitude, &wpt->longitude, 1);
     break;
   case XcsvStyle::XT_LAT_DDMMDIR:
     wpt->latitude = ddmmdir_to_degrees(s);
@@ -479,7 +479,7 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
     wpt->longitude = intdeg_to_dec((int) atof(s));
     break;
   case XcsvStyle::XT_LON_HUMAN_READABLE:
-    human_to_dec(s, &wpt->latitude, &wpt->longitude, 2);
+    human_to_dec(value, &wpt->latitude, &wpt->longitude, 2);
     break;
   case XcsvStyle::XT_LON_DDMMDIR:
     wpt->longitude = ddmmdir_to_degrees(s);
@@ -490,7 +490,7 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
   // case XcsvStyle::XT_LON_10E is handled outside the switch.
   /* LAT AND LON CONVERSIONS ********************************************/
   case XcsvStyle::XT_LATLON_HUMAN_READABLE:
-    human_to_dec(s, &wpt->latitude, &wpt->longitude, 0);
+    human_to_dec(value, &wpt->latitude, &wpt->longitude, 0);
     break;
   /* DIRECTIONS **********************************************************/
   case XcsvStyle::XT_LAT_DIR:
@@ -638,7 +638,7 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
     break;
   case XcsvStyle::XT_ISO_TIME:
   case XcsvStyle::XT_ISO_TIME_MS:
-    wpt->SetCreationTime(xml_parse_time(s));
+    wpt->SetCreationTime(xml_parse_time(value));
     break;
   case XcsvStyle::XT_NET_TIME: {
     bool ok;